#include "rebuilding_operations.h"
#include "mainwindow.h"
#include "resource.h"

EmbossSettings embossSettings;

bool flipHorizontalSetup( Task *task )
{
	return true;
}

bool flipHorizontal( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool flipVerticalSetup( Task *task )
{
	return true;
}

bool flipVertical( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool medianSetup( Task *task )
{
	return true;
}

bool median( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool averageSetup( Task *task )
{
	return true;
}

bool average( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

BOOL CALLBACK embossSetupProc(
	HWND hWndDialog,
	UINT message,
	WPARAM wParam,
	LPARAM lParam )
{
	switch( message )
	{
	case WM_INITDIALOG:
		//This message is send when the dialog is about to be initialized.
		//We set the default values for the edit controls.
		SetDlgItemText( hWndDialog, IDC_EDIT_EMBOSS_X, L"1" );
		SetDlgItemText( hWndDialog, IDC_EDIT_EMBOSS_Y, L"1" );
		break;
	case WM_COMMAND:
		switch( LOWORD( wParam ) )
		{
		case IDOK:
			{
				//Read the values the user entered and store them in embossSettings.
				wchar_t szXOffset[32], szYOffset[32];

				if( GetDlgItemText( hWndDialog, IDC_EDIT_EMBOSS_X, szXOffset, 32 ) == 0 || 
					GetDlgItemText( hWndDialog, IDC_EDIT_EMBOSS_Y, szYOffset, 32 ) == 0 )
				{
					//One or more fields are left empty. Show a warning and do not close the dialog.
					MessageBox( hWndDialog, L"Invalid input", L"Message", MB_OK | MB_ICONEXCLAMATION );
					return FALSE;
				}

				//If text is entered as the x or y offset, the value will be set to 0 by _wtoi.
				//It is not easy to change this behaviour. Setting the 'Number' propery of the
				//edit box would not allow negative numbers.
				embossSettings._xOffset = _wtoi( szXOffset );
				embossSettings._yOffset = _wtoi( szYOffset );
			}
		case IDCANCEL:
			EndDialog( hWndDialog, wParam );
			return TRUE;
		}
		break;
	}
	return FALSE;
}

bool embossSetup( Task *task )
{
	MainWindow *mainWindow = MainWindow::instance();
	if( DialogBox(
		mainWindow->hInstance(),
		MAKEINTRESOURCE( IDD_DIALOG_EMBOSS ),
		mainWindow->hWnd(),
		(DLGPROC) &embossSetupProc ) == IDOK )
	{
		//Allocate a structure and copy the settings. This structure is used in
		//the emboss method.
		task->_data = new EmbossSettings( embossSettings );
		return true;
	}
	return false; //The user cancelled the operation.
}

bool emboss( Image &imgSource, Image &imgResult, void *data )
{
	int xOffset, yOffset;
	unsigned int xPos, yPos;

	xOffset = ( (EmbossSettings*) data )->_xOffset;
	yOffset = ( (EmbossSettings*) data )->_yOffset;

	for( unsigned int row = 0; row < imgSource.height(); ++row )
	{
		yPos = min( (unsigned int) max( (int) row + yOffset, 0 ), imgSource.height() - 1 );

		for( unsigned int col = 0; col < imgSource.width(); ++col )
		{
			xPos = min( (unsigned int) max( (int) col + xOffset, 0 ), imgSource.width() - 1 );

			for( unsigned int channel = 0; channel < 3; ++channel )
			{
				imgResult[ row ][ col ][ channel ] =
					imgSource[ row ][ col ][ channel ] / 2 +
					( imgSource[ yPos ][ xPos ][ channel ] ^ 0xFF ) / 2;
			}
		}
	}

	delete data;
	return true;
}

bool gaussSetup( Task *task )
{
	return true;
}

bool gauss( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool sobelHorizontalSetup( Task *task )
{
	return true;
}

bool sobelHorizontal( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool sobelVerticalSetup( Task *task )
{
	return true;
}

bool sobelVertical( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool laplaceSetup( Task *task )
{
	return true;
}

bool laplace( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}

bool discreteCosineTransformSetup( Task *task )
{
	return true;
}

bool discreteCosineTransform( Image &imgSource, Image &imgResult, void *data )
{
	return true;
}
